//服务接口的编辑器，包括个性化接口属性， 操作数，operate面板，参数面板
define(function(require, exports, module) {

	//lib工具包
	require('resources/js/avalon-2.0.js');
	//组件
	require('resources/js/component/EdiMenu.js');
	var RemoteCache=require('resources/js/component/RemoteCache.js');
	
	var serviceOperateTpl=require('text!resources/template/resInfo/resInfo_service_editor_tpl.html');
	var ResInfoBaseEditor=require('resources/template/resInfo/resInfo_base_editor.js');
	var resInfoBaseEditorTpl=require('text!resources/template/resInfo/resInfo_base_editor_tpl.html');
	
	//公用逻辑
	var domain=require('common/domain.jhtml?');
	var resConstants=require('resources/js/rescatalogMix/res_constants.js');
	
	/***/
	var ServiceOperatePlugin=function(data,$container,config){
		//各个组件初始化
		this.$container=$container
		this.resInfo=data;
		
		this.baseUrl=config.baseUrl;
		this.selfDelete=config.selfDelete===undefined?true:config.selfDelete;
		this.readOnly=config.readOnly===undefined?false:config.readOnly;
		this.step=config.step||'draft';
		
		this.$div=$(serviceOperateTpl).prependTo($container);
		this.$resInfoBaseDiv=$('.base-property',this.$div);
		$(resInfoBaseEditorTpl).prependTo(this.$resInfoBaseDiv);
		
		this.init();
	}
	ServiceOperatePlugin.remoteCache=new RemoteCache();
	
	ServiceOperatePlugin.prototype={
		get:function(key){
			return ServiceOperatePlugin.remoteCache.get(key)
		},
		getCmpConfig:function(){
			return {
				step:this.step,
				baseUrl:this.baseUrl,
				readOnly:this.readOnly
			};
		},
		init:function(){
			ServiceOperatePlugin.remoteCache.get('resServiceType',this.getUrl('resServiceType'));
			ServiceOperatePlugin.remoteCache.get('resServiceTypeProp',this.getUrl('resServiceTypeProp'));
			
			//个性化属性表单
			this.serviceProp=new ServiceProp($('.service-prop-container',this.$div),this);
			//操作树菜单
			this.dbOperateMenu=new DBOperateMenu(this);
			//节点类型及其面板
			this.nodeType=new NodeType(this);
			//操作树
			this.operateTree=new OperateTree($('.operateTree',this.$div),this);
			this.render();
			this.bind();
			this.resInfoBaseEditor=new ResInfoBaseEditor(this.resInfo,this.$resInfoBaseDiv,this.getCmpConfig());
			
			this.sync();
			this.readOnlyRender();
		},
		render:function(){
			
		},
		readOnlyRender:function(){
			if(!this.readOnly)
				return ;
			
			$('input,textarea',this.$div).attr('readonly','readonly');
			$('select',this.$div).attr('disabled','disabled');
			$('[name=paramNullable]',this.$div).bootstrapToggle('disable');
		},
		bind:function(){
			var that=this;
			$('select[name="serviceType"]',this.$div).on('change',function(){
					that.serviceProp.changeServiceType(this.value);
					var ztreeObj=that.operateTree.ztreeObj,
						operateCode=that.operateCode;
					if(operateCode=='create'&&this.value=='1'&&
							!ztreeObj.getNodeByParam("id","operateTree-operate-default"))
					{
						var treeNode=ztreeObj.getNodes()[0];
						ztreeObj.addNodes(treeNode,nodeType.createOperateNode(treeNode,"operateTree-operate-default","default"));
					}	
					
			});
			/*$('.importWS',this.$div).on('click',function(){
				var value=$(this).prev().val();
				if(!value)
					return;
				that.loadWebServiceOperate(value);
			});*/
		},
		sync:function(){
			var that=this,resInfo=this.resInfo,service=resInfo.service,
				$vmId='resInfo-service-'+resInfo.resId;
			this.$div.attr("ms-controller",$vmId);
			//使用avalon渲染
			this.vm = avalon.define({
                $id: $vmId,
                resInfo:resInfo,
                selfDelete:this.selfDelete,
                step:this.step,
                resServiceType:this.get('resServiceType'),
                $skipArray:['resInfo.service','resInfo.service.operates']
            });//联合资源的vm
			avalon.scan(this.$div.get(0),this.vm);
			this.operateTree.fillServiceData(service);
			this.serviceProp.fillData(service.serviceType, service.serviceProps);
			this.resInfoBaseEditor.fillData(this.vm.resInfo);
		},
		getServiceType:function(){
			return this.vm.resInfo.service.serviceType;
		},
		operateURL:{
			'create':'/service/saveService.jhtml',
			'edit':'/service/updateService.jhtml',
			'loadWSOperate':'/service/loadWSOperate.jhtml',
			'testWS':'/service/testWS.jhtml',
			'testHttp':'/service/testHttp.jhtml',
			'resServiceType':'/resservice/serviceType.jhtml',
			'resServiceTypeProp':'/resservice/serviceTypeProp.jhtml'
		},
		getUrl:function(code){
			return this.baseUrl+this.operateURL[code];
		},
		getFlatOperate:function(operates,container){
			var that=this;
			$.each(operates,function(index,operate){
				if(operate.nodeType==0)
					container.push(operate);
				else
					operate.children&&that.getFlatOperate(operate.children,container);
			})
		},
		getData:function(){
			var errorMsg=this.resInfoBaseEditor.getError();//这里要放在提取this.resInfo之前
			this.resInfo=this.vm.resInfo.$model;
			this.resInfo.service.serviceProps=this.serviceProp.getData();
			this.resInfo.service.operates=this.operateTree.getData();
			
			var service=this.resInfo.service;
			var serviceTypeValue=service.serviceType;
			if(!serviceTypeValue)
				errorMsg.push('服务类型必填!');
			else
				errorMsg=errorMsg.concat(this.serviceProp.getError());
			
			//operate:重名，空，
			var duplicate={},operates=[];
			this.getFlatOperate(service.operates, operates);
			$.each(operates,function(index,operate){
				if(!operate.operateName)
					errorMsg.push('第'+(index+1)+'个操作没有名称!');
				else if(operate.operateName&&duplicate[operate.operateName])
					errorMsg.push('第'+(index+1)+'个操作：'+operate.operateName+'已存在!');
				else
					duplicate[operate.operateName]=operate;
				
				//operate-param，paramName,paramType必填
				var params=operate.params,pDuplicate={};
				params&&$.each(params,function(pIndex,param){
					if(!param.paramName)
						errorMsg.push('第'+(index+1)+'个操作的第'+(pIndex+1)+'参数没有名称!');
					else if(param.paramName&&pDuplicate[param.paramName])
						errorMsg.push('第'+(index+1)+'个操作的第'+(pIndex+1)+'参数:'+param.paramName+'名称已存在!');
					else
						pDuplicate[param.paramName]=param;
					if(param.paramType===undefined||param.paramType==='')
						errorMsg.push('第'+(index+1)+'个操作的第'+(pIndex+1)+'参数没有设置类型!');
				});
			});
			!operates.length&&errorMsg.push('至少添加一个操作');
			this.resInfoError=errorMsg;
		},
		loadWebServiceOperate:function(url){
			//ajax请求后台的operate信息，先判断前面的文本框是否有值。
			$.ajax(domain.edi+this.operateURL['loadWSOperate'],{
				data:{url:url},
				type:'POST',
				dataType:'json'
			}).done(function(data){
				if(data&&data.code)
					return tip(data.note);
				
				if(!data||data.length==0)
					return;
				
				var operateTree=that.operateTree,
					ztreeObj=operateTree.ztreeObj,
					rootNode =operateTree.rootNode;
					ztreeObj.removeChildNodes(rootNode);
					$.each(data,function(index,operate){
						var operateIndex=operateTree.treeNodeCount++,
						inParamIndex=operateTree.treeNodeCount++,
						outParamIndex=operateTree.treeNodeCount++,
						outParam,inParams=[];
						operate.params&&$.each(operate.params,function(index,param){
							if(param.inOut==1)
								inParams.push({
									id : "operateTree" + operateTree.treeNodeCount++,
									pId : "operateTree" + inParamIndex,
									isParent : false,
									name:param.paramName||'param',
									nodeType:'param',
									paramName:param.paramName||'param',
									paramAlias:param.paramAlias||param.paramName||'param',
									paramType:resConstants.typeArray[param.paramType]
								});
							else(param.inOut==0)
								outParam={
									id : "operateTree" + operateTree.treeNodeCount++,
									pId : "operateTree" + outParamIndex,
									isParent : false,
									name:param.paramName||'param',
									nodeType:'param',
									paramName:param.paramName||'param',
									paramAlias:param.paramAlias||param.paramName||'param',
									paramType:resConstants.typeArray[param.paramType]
								};
						});
						ztreeObj.addNodes(rootNode,{
							id : "operateTree" + operateIndex,
							pId : rootNode.id,
							isParent : true,
							open:true,
							name:operate.operateName||'operate',
							nodeType:'operate',
							request:operate.request,
							response:operate.response,
							operateName:operate.operateName||'operate',
							children:[{
								id : "operateTree" + inParamIndex,
								pId : "operateTree" + operateIndex,
								isParent : true,
								name:'入参',
								nodeType:'in-param-desc',
								open:true,
								children:inParams
							},{
								id : "operateTree" + outParamIndex,
								pId : "operateTree" + operateIndex,
								isParent : true,
								open:true,
								name:'出参',
								nodeType:'out-param-desc',
								children:[outParam]
							}]
						});
					});
					basePanelWgt.hide();
				}).fail(function(e){
					console.log(e);
				});
		},
		destroy:function(){
			this.$div.remove();
		}
	};
	
	var ServiceProp=function($div,parent){
		this.parent=parent;
		this.$div=$div;
		this.render();
	}
	ServiceProp.prototype={
		getServiceType:function(){
			return $('[serviceType]:visible',this.$div).attr('serviceType');
		},
		getData:function(){
			var serviceProps=[],$serviceProp=$('.service-prop:visible',this.$div);
			if($serviceProp)
				$.each($('input,select',$serviceProp),function(index,ele){
					serviceProps.push(ele.name+"="+ele.value);
				});
			return serviceProps.join("\n");
		},
		getError:function(){
			//service-prop
			var errorMsg=[],serviceType=this.getServiceType();
				serviceProp=this.parent.get('resServiceTypeProp')[serviceType],
				$serviceProp=$('.service-prop:visible',this.$div);
			
			$.each(serviceProp,function(index,ele){
				//require
				var propField=$('[name='+ele.propKey+'][propRequire=1]',$serviceProp);
				propField.length>0&&!propField.val()&&errorMsg.push(ele.propName+'必填!');
				//正则判断，是否符合格式
				var propField=$('[name='+ele.propKey+'][propFormat]',$serviceProp);
				propField.length>0&&propField.val()
					&&!new RegExp(propField.attr('propFormat')).test(propField.val())
					&&errorMsg.push(ele.propName+'格式不对!');
			});
			return errorMsg;
		},
		changeServiceType:function(serviceType){
			$('[serviceType]',this.$div).css('display','none');
			$('[serviceType='+serviceType+']',this.$div).css('display','block');
			var nodeType=this.parent.nodeType;
			//操作树的节点显示
			nodeType.nodeBtnShow();
			//根节点的panel显示
			nodeType.root.panelWidget.showContent();
		},
		fillData:function(serviceType,data){
			this.changeServiceType(serviceType)
			if(!data)
				return;
			
			var values=this.parseKeyValue(data),
				$serviceProp=$('.service-prop:visible',this.$div);
			$.each($('input,select',$serviceProp),function(index,ele){
				values[ele.name]&&(ele.value=values[ele.name]);
			});
		},
		parseKeyValue:function(str){
			var res={},item;
			while((item=this.parttern.exec(str))!=null){
				res[item[1]]=item[2];
			}
			return res;
		},
		parttern:/([^=\n\s]+)=([^\n\s]+)/g,
		render:function(){
			var props,that=this,
				typeProps=this.parent.get('resServiceTypeProp');
			
			var inputHtml=function(prop,propHtml,serviceType){
				propHtml.push('<label for="'+prop.propKey+'" class="col-xs-2 control-label">'+prop.propName+'：</label>');
				propHtml.push('<div class="col-xs-4">');
				
				var optionsArray,optionEleArray,valueStr=prop.propDefault==null?'':(' value="'+prop.propDefault+'" '),
					htmlProp=(prop.propRequire?' propRequire="'+prop.propRequire+'"':'')+
						(prop.propMaxlen?' maxlength="'+prop.propMaxlen+'"':'')+
						(prop.propFormat?' propFormat="'+prop.propFormat+'"':'')+' type="input" class="form-control"/>';
				if(prop.propOptions)
				{
					propHtml.push('<select name="'+prop.propKey+'" class="form-control">');
					propHtml.push('<option value="">请选择</option>');
					var values=that.parseKeyValue(prop.propOptions);
					for(key in values)
						propHtml.push('<option value="'+key+'">'+values[key]+'</option>');
					propHtml.push('</select>');
				}
				//特殊处理，webservice的url
				/*else if(serviceType==2&&prop.propKey=='url')
				{
					propHtml.push('<input name="'+prop.propKey+'"  style="width:80%;float:left" '+htmlProp);
					propHtml.push('<button type="button" style="float:left;width:18%;margin-left:2%" class="importWS btn btn-default">导入</button>');
				}	*/
				else if(serviceType==3&&prop.propKey=='url')
				{
					propHtml.push('<input name="'+prop.propKey+'" httpUrl '+htmlProp);
				}	
				else 
					propHtml.push('<input name="'+prop.propKey+'" '+valueStr+htmlProp);
				propHtml.push('</div>');
			};
			
			var propHtml=[];
			for(var serviceType in typeProps)
			{
				props=typeProps[serviceType];
				var propIndex=0;
				propHtml.push('<div serviceType="'+serviceType+'" style="display: none" class="service-prop">');
				for(;props&&propIndex<props.length;propIndex+=2)
				{
					propHtml.push('<div class="form-group ">');
					inputHtml(props[propIndex],propHtml,serviceType);
					propIndex+1<props.length&&inputHtml(props[propIndex+1],propHtml,serviceType);
					propHtml.push('</div>');
				}	
				propHtml.push('</div>');
			}	
			this.$div.append(propHtml.join(""));
		}
	};
	
	var OperateTree=function($div,parent){
		this.$tree=$div;
		this.parent=parent;
		this.datas=[];
		this.init();
	};
	OperateTree.treeNodeCount=0;
	OperateTree.prototype={
		fillServiceData:function(service){
			if(service.operates==undefined||service.operates.length==0)
				return;
			var ztreeData=$.map(service.operates.$model,function(operate){
				if(operate.params!=undefined&&operate.params.length>0)
				{	
					operate.params=$.map(operate.params,function(param){
						param.paramType=resConstants.typeArray[param.paramType];
						param.name=param.paramAlias;
						return param;
					});
				}
				operate.name=operate.operateName||'';
				operate.id=operate.operateId;
				operate.isParent=true;
				operate.pId=operate.parentId&&operate.parentId!=0?operate.parentId:'_root_';
				operate.nodeType=operate.nodeType&&operate.nodeType==1?'group':'operate';
				return operate;
			});
			ztreeData=this.adapterData(ztreeData);
			this.datas=this.datas.concat(ztreeData);
			this.ztreeObj.addNodes(this.ztreeObj.getNodes()[0],ztreeData,false);
			this.ztreeObj.expandAll(true);
		},
		getEditableTreeSetting:function(){
			var that=this;
			return {
				data : {
					keep : {
						parent : true
					},
					simpleData : {
						enable : true
					}
				},
				edit : {
					enable : true,
					showRemoveBtn : false,
					showRenameBtn : false
				},
				view : {
					dblClickExpand : false,
					selectedMulti : false,
					addDiyDom : function(treeId, treeNode) {
						var aObj = $("#" + treeNode.tId + "_a"),
							editStr = that.parent.nodeType[treeNode.nodeType].btnHtml(treeId, treeNode);
						aObj.append(editStr);
					}
				},
				callback : {
					onRename : function(event, treeId, treeNode, isCancel) {
						if (isCancel)
							return false;
						
						if(treeNode.name.length>25)
							treeNode.name=treeNode.name.substring(0,25);
						
						if (treeNode.elementFlag && treeNode.name.charAt(0) !== '@')
							treeNode.name = "@" + treeNode.name;
						
						var nodeTypeInstance=nodeType[treeNode.nodeType];
						nodeTypeInstance.canRename()
						&&nodeTypeInstance.panelWidget.afterRename
						&&nodeTypeInstance.panelWidget.afterRename(treeNode,treeNode.name);
					},
					onDblClick : function(event, treeId, treeNode) {
						if (!treeNode)
							return;
						//if(that.parent.serviceProp.getServiceType()=='2')
						//	return false;
						
						that.parent.nodeType[treeNode.nodeType].canRename()&&that.ztreeObj.editName(treeNode);
					},
					onClick : function(event, treeId, treeNode) {
						that.parent.nodeType[treeNode.nodeType].panelWidget.show(treeId, treeNode);
					}
				}
			};
		},
		getReadOnlyTreeSetting:function(){
			var that=this;
			return {
				data : {
					keep : {
						parent : true
					},
					simpleData : {
						enable : true
					}
				},
				view : {
					selectedMulti : false
				},
				callback : {
					onClick : function(event, treeId, treeNode) {
						that.parent.nodeType[treeNode.nodeType].panelWidget.show(treeId, treeNode);
					}
				}
			};
		},
		init:function(){
			var that=this,nodeType=this.parent.nodeType;
			this.datas.push(nodeType["root"].instance);
			
			this.treeSetting=this.parent.readOnly?this.getReadOnlyTreeSetting():this.getEditableTreeSetting();
			this.$tree.attr('id','operateTree-'+this.parent.resInfo.resId);
			this.ztreeObj = $.fn.zTree.init(this.$tree, this.treeSetting, this.datas);
			this.ztreeObj.expandAll(true);
			this.rootNode=this.ztreeObj.getNodes()[0];
			this.parent.dbOperateMenu.init();
			this.bind();
		},
		bind:function(){
			var that=this,
				nodeType=this.parent.nodeType,
				dbOperateMenu=that.parent.dbOperateMenu;
			this.$tree.on('click', '.diy_delete', function(event) {
				var treeNode = that.ztreeObj.getNodeByTId(this.getAttribute('treeTId'));
				var node = that.ztreeObj.getSelectedNodes()[0],
					parentNode=treeNode.getParentNode();
				if(node&&node.id==treeNode.id)
					nodeType[treeNode.nodeType].panelWidget.disableFieldProperties();
				that.ztreeObj.removeNode(treeNode);
				//限制出参只有一个，恢复添加按钮
				if(parentNode.nodeType=='out-param-desc')
				{
					$('#'+parentNode.tId+' [treetid='+parentNode.tId+']').css('display','inline-block');
				}
				else if(parentNode.nodeType=='root')
					dbOperateMenu.showRootAddBtn();
				return false;
			});
			this.$tree.on('click', '.diy_add', function(event) {
				var treeNode = that.ztreeObj.getNodeByTId(this.getAttribute('treeTId')),
					childNode=nodeType[treeNode.nodeType].createChildNode(treeNode);
				that.ztreeObj.addNodes(treeNode, childNode);
				//限制出参只有一个
				if(treeNode.nodeType=='out-param-desc'&&treeNode.children.length==1)
				{
					$(this).css('display','none');
				}
				return false;
			});
			this.$tree.on('click', '.diy_add_group', function(event) {
				var treeNode = that.ztreeObj.getNodeByTId(this.getAttribute('treeTId')),
					groupNode=nodeType[treeNode.nodeType].createGroupNode(treeNode);
				that.ztreeObj.addNodes(treeNode, groupNode);
				return false;
			});	
		},
		getOperateData:function(node){
			var operate={
				operateId:node.operateId||0,
				serviceId:node.serviceId||0,
				operateName:node.operateName,
				operateMemo:node.operateMemo,
				request:node.request,
				response:node.response?node.response.substr(0,900):""
			},that=this;
			if(node.nodeType=='group')
			{
				operate.nodeType=1;
				node.children&&(operate.children=$.map(node.children,function(child){
					return that.getOperateData(child);
				}));
			}	
			else if(node.nodeType=='operate')
			{
				operate.params=[];
				operate.nodeType=0;
				$.each(node.children,function(index,paramDescNode){
					paramDescNode.children&&$.each(paramDescNode.children,function(index,paramNode){
						operate.params.push(that.getParamOperateData(paramNode, paramDescNode.nodeType=='in-param-desc'?1:0));
					})
				});
			}
			return operate;
		},
		getParamOperateData:function(node,inOut){
			return {
				paramId:node.paramId||0,
				operateId:node.operateId||0,
				inOut:inOut,
				paramType:resConstants._getTypeCode[node.paramType],
				paramFormat:node.paramFormat,
				paramTypeLen:node.paramTypeLen,
				paramNullable:node.paramNullable,
				maxVal:node.maxVal,
				minVal:node.minVal,
				paramAlias:node.paramAlias,
				paramName:node.paramName,
				memo:node.memo
			};
		},
		getData:function(){
			var operateNodes=this.ztreeObj.getNodes()[0].children,that=this;
			return operateNodes?$.map(operateNodes,function(operateNode){
				return that.getOperateData(operateNode);
			}):[];
		},
		adapterData:function(ztreeData){
			return $.map(ztreeData,function(data){
				if(data.nodeType=='group')
					return data;
				var inParamDesc={
						id : "in-param" + data.operateId,
						pId : data.operateId,
						isParent : true,
						name:'入参',
						nodeType:'in-param-desc',
						children:[]
					},
					outParamDesc={
						id : "out-param" + data.operateId,
						pId : data.operateId,
						isParent : true,
						name:'出参',
						nodeType:'out-param-desc',
						children:[]
					};
				data.params&&$.each(data.params,function(index,param){
					if(param.inOut==1)
						inParamDesc.children.push($.extend(param,{pId:inParamDesc.id,nodeType:'param'}));
					else if(param.inOut==0)
						outParamDesc.children.push($.extend(param,{pId:outParamDesc.id,nodeType:'param'}));
				});
				return $.extend(data,{children:[inParamDesc,outParamDesc]});
			});
		}
	};
	
	
	/**############################################################################################
	 * panel树旁的面板：描述面板(root,param-in-out-desc,)，操作面板，参数面板
	 * show(treeId, treeNode);
	 * disableFieldProperties()
	 *#############################################################################################*/
	var BasePanelWgt=function(){
		
	}
	BasePanelWgt.prototype={
		show:function(treeId, treeNode){
			this.beforeShow&&this.beforeShow(treeId, treeNode);
			this.$panels.css("display","none");
			this.$id.css("display","block");
			this.afterShow&&this.afterShow(treeId, treeNode);
		},
		hide:function(){
			this.$panels.css("display","none");
		}
	};
	/***描述面板(root,param-in-out-desc,)*/
	var DescPanelWgt=function($pDiv,parent,desc)
	{
		this.parent=parent;
		this.$panels=$('.node-panel',$pDiv);
		this.$id=$('.descPanel',$pDiv);
		this.$descText=$('.descText',this.$id);
		this.desc=desc;
		this.init();
	};
	DescPanelWgt.prototype={
		beforeShow:function(treeId, treeNode){
			this.$descText.html(this.desc);
			this.showContent();
		},
		init:function(){
			
		},
		disableFieldProperties:function(){
			this.$id.css('display','none');
		},
		showContent:function(){
			//this.parent.serviceProp.getServiceType()=='2'&&this.$descText.css('display','none')||
			this.$descText.css('display','block');
		}		
	};
	$.extend(DescPanelWgt.prototype,new BasePanelWgt());

	var OperatePanelWgt=function($pDiv,parent)
	{
		this.parent=parent;
		this.$panels=$('.node-panel',$pDiv);
		this.$id=$('.operatePanel',$pDiv);
		this.type='operate';
		this.init();
	};
	OperatePanelWgt.prototype={
		disableFieldProperties:function(){
			this.$id.css('display','none');
		},
		init:function(){
			var that=this;
			this.$id.on('keyup','input[type=text]',function(){
				var ztreeObj=that.parent.operateTree.ztreeObj,
					node = ztreeObj.getSelectedNodes()[0];
				if (!node)
					return;
				node[this.name] = this.value;
				if(this.name=='operateName')
				{
					node.name=this.value;
					node.operateName=this.value;
					ztreeObj.updateNode(node);
				}	
			});
			return this;
		},
		afterRename:function(treeNode,name){
			$('input[name=operateName]',this.$id).val(name);
			treeNode.operateName = name;
		},
		beforeShow:function(treeId, treeNode){
			$.each($('.readbind', this.$id),
					function(index, ele) {
						var value = treeNode[ele.getAttribute('name')]||'';
						bingding.clickPropertiesBind(this, value);
					});
			//if(this.type=='operate')
				//testPanel.show(treeId, treeNode);  TODO-lisn 暂时不要的功能，接口测试
		}
	};
	$.extend(OperatePanelWgt.prototype,new BasePanelWgt());

	var GroupPanelWgt=function($pDiv,parent)
	{
		this.parent=parent;
		this.$panels=$('.node-panel',$pDiv);
		this.$id=$('.groupPanel',$pDiv);
		this.init();
	};
	$.extend(GroupPanelWgt.prototype,new OperatePanelWgt());
	
	
	var ParamPanelWgt=function($pDiv,parent)
	{
		this.parent=parent;
		this.$panels=$('.node-panel',$pDiv);
		this.$id=$('.paramPanel',$pDiv);
		this.$input=$('.paramPanel input,.paramPanel select',$pDiv);
		this.init();
	};
	ParamPanelWgt.prototype={
		disableFieldProperties:function(){
			this.$id.css('display','none');
		},
		afterRename:function(treeNode,name){
			$('[name=paramAlias]',this.$id).val(name);
			treeNode.paramAlias = name;
		},
		beforeShow:function(treeId, treeNode){	//对应树节点信息内容展示
			$.each($('.readbind', this.$id),
					function(index, ele) {
						var value = treeNode[ele.getAttribute('name')]||'';
						bingding.clickPropertiesBind(this, value);
					});
			var $paramNullable=$('[name=paramNullable]',this.$id);
			if(treeNode['paramNullable']===1)
				$paramNullable.bootstrapToggle('off').prop('checked',false);
			else
				$paramNullable.bootstrapToggle('on').prop('checked',true);
			this.paramTypeFieldShow(treeNode.paramType);
		},
		paramTypeFieldShow:function(value){
			if(value=='string'||value=='object'||value=='array')
				$('.prot-field',this.$id).css('display','block');
			else
				$('.prot-field' ,this.$id).css('display','none');
		},
		init:function(){
			$('[name=paramNullable]',this.$id).bootstrapToggle({
		      	on: '空',
		      	off: '非空',
		      	size:'mini',
		      	width:45,
		      	toggle:'toggle'
		    });
			var that=this;
			$('[name=paramType]',this.$id).on('change',function(){
				that.paramTypeFieldShow(this.value);
			});
			this.$id.on('change','select,input[type!=text]',function(){
				var node = that.parent.operateTree.ztreeObj.getSelectedNodes()[0];
				if (!node||this.name=='paramNullable')
					return;
				node[this.name] = this.value;
			});
			//普通文本框   写绑定
			this.$id.on('keyup','input[type=text]',function(){
				var ztreeObj=that.parent.operateTree.ztreeObj,
					node = ztreeObj.getSelectedNodes()[0];
				if (!node)
					return;
				
				if(this.name=='paramAlias')
				{
					node.name=this.value;
					ztreeObj.updateNode(node);
				}	
				else if(this.name=='paramName'&&node.inOut==1)
				{
					var operateNode=node.getParentNode().getParentNode(),request=operateNode.request;
					if(request)
					{
						request=request.replace(node.paramName,node.name);
						operateNode.request=request;
					}
				}
				node[this.name] = this.value;
			});
			//开关组件的   写绑定
			$('.checkbox-inline',this.$id).click(function() {
				var ztreeObj=that.parent.operateTree.ztreeObj,
					node = ztreeObj.getSelectedNodes()[0];
				if (!node)
					return;
				var $input=$('input',this),name=$input.attr("name");
				if(name=='paramNullable')
					node[name]= $input.prop('checked')?1:0;
			});
			return this;
		}
	};
	$.extend(ParamPanelWgt.prototype,new BasePanelWgt());
	


	var DBOperateMenu=function(parent){
		this.parent=parent;
	};
	DBOperateMenu.prototype={
		codeIdMap:{
			'create':"operateTree-operate-create",
			'retrieve':	"operateTree-operate-retrieve",
			'update':"operateTree-operate-update",
			'delete':"operateTree-operate-delete",
			'default':"operateTree-operate-default"
		},
		show:function(treeNode){
			this.menu.showMenu('db-operate',treeNode);
		},
		showMenuItem:function(code){
			return !this.parent.operateTree.ztreeObj.getNodeByParam("id",this.codeIdMap[code]);
		},
		showRootAddBtn:function(){
			var operateTree=this.parent.operateTree
				ztreeObj=operateTree.ztreeObj,
				showCount=0;
			for(var codeTemp in this.codeIdMap)
				if(ztreeObj.getNodeByParam("id",this.codeIdMap[codeTemp]))
					showCount++;
			if(showCount==5)
				$('.node-root-add',operateTree.$tree).css('display','none');
			else
				$('.node-root-add',operateTree.$tree).css('display','inline-block');
		},
		init:function(){
			var that=this;
			this.menu=new EdiMenu({
				minWidth:120,
				menu:[{
						type:'db-operate',
						items:[{
									name:'默认操作',	
									code:'default',
									isShow:function(){
										return that.showMenuItem(this.code)
									}
								},{
									name:'新增操作',	
									code:'create',
									isShow:function(){
										return that.showMenuItem(this.code)
									}
								},{
									name:'抽取操作',	
									code:'retrieve',
									isShow:function(){
										return that.showMenuItem(this.code)
									}
								},{
									name:'更新操作',	
									code:'update',
									isShow:function(){
										return that.showMenuItem(this.code)
									}
								},{
									name:'删除操作',	
									code:'delete',
									isShow:function(){
										return that.showMenuItem(this.code)
									}
								}]
					}],
				onclickItem:function(type,code,commandData){
					var operateTree=that.parent.operateTree,
						ztreeObj=operateTree.ztreeObj,
						treeNode=commandData,
						operateId=that.codeIdMap[code];
					ztreeObj.addNodes(treeNode,that.parent.nodeType.createOperateNode(treeNode,operateId,code));
					that.showRootAddBtn();
				}	
			});	
		}
	};
	
	/**################各种节点的各种回调################################################*/
	var NodeType=function(parent){
		this.$div=$('.panelContainer',parent.$div);
		this.parent=parent;
		this.init();
	};
	NodeType.prototype={
		createGroupNode:function(treeNode,id,name){
			var operateIndex=OperateTree.treeNodeCount++;
			return {
				id : "operateTree" + operateIndex,
				pId : treeNode.id,
				operateId:-operateIndex,
				isParent : true,
				name:name||'group',
				nodeType:'group',
				operateName:name||'group'
			};
		},
		createOperateNode:function(treeNode,id,name){
			var operateIndex=OperateTree.treeNodeCount++,
			inParamIndex=OperateTree.treeNodeCount++,
			outParamIndex=OperateTree.treeNodeCount++;
			return {
				id : id||"operateTree" + operateIndex,
				operateId:-operateIndex,
				pId : treeNode.id,
				isParent : true,
				open:true,
				name:name||'operate',
				nodeType:'operate',
				operateName:name||'operate',
				children:[{
					id : "operateTree" + inParamIndex,
					pId : "operateTree" + operateIndex,
					isParent : true,
					name:'入参',
					nodeType:'in-param-desc'
				},{
					id : "operateTree" + outParamIndex,
					pId : "operateTree" + operateIndex,
					isParent : true,
					name:'出参',
					nodeType:'out-param-desc'
				}]
			};
		},
		initRoot:function(){//根节点
			var that=this;
			this["root"]={
					instance:{
						id:"_root_",
						name:"服务操作",
						isParent:true,
						nodeType:"root"
					},
					panelWidget:new DescPanelWgt(this.$div,this.parent,"点击增加按钮，添加“操作”；点击分组按钮，增加分组"),
					btnHtml:function(treeId, treeNode){//增加 操作 节点
						return "<span class='diy diy_add node-root node-root-add' "
						+"' treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='增加操作' "+
						that.parent.nodeType.addBtnAppendStyle(treeNode)+"/>"
						+"<span class='diy diy_add_group node-root node-root-add-group' treeId='"+treeId+"' treeTId='"+treeNode.tId +"' title='增加分组' "+
						that.parent.nodeType.groupBtnAppendStyle(treeNode)+"/>";
					},
					canRename:function(){return false;},
					createGroupNode:function(treeNode,id,name){
						return that.parent.nodeType.createGroupNode(treeNode,id,name);
					},
					createChildNode:function(treeNode,id,name){	//创建一个operate操作-节点
						if(that.parent.getServiceType()!='1')
							return that.parent.nodeType.createOperateNode(treeNode,id,name);
						else
						{
							//如果服务类型是数据库则弹出可选择的菜单
							that.parent.dbOperateMenu.show(treeNode);
						}
					}
			};
		},
		initGroup:function(){//操作分组节点
			var that=this;
			this["group"]={
					panelWidget:new GroupPanelWgt(this.$div,this.parent),
					canRename:function(){return true;},
					btnHtml:function(treeId, treeNode){//增加 操作 节点
						return "<span class='diy diy_add node-group'  treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='增加操作' "+
						that.parent.nodeType.addBtnAppendStyle(treeNode)+"/>"
						+"<span class='diy diy_add_group node-group'  treeId='"+treeId+"' treeTId='"+treeNode.tId +"' title='增加分组' "+
						that.parent.nodeType.groupBtnAppendStyle(treeNode)+"/>"+
						"<span class='diy diy_delete node-group'  treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='删除' "+
						that.parent.nodeType.deleteBtnAppendStyle(treeNode)+"/>";
					},
					createGroupNode:function(treeNode,id,name){
						return that.parent.nodeType.createGroupNode(treeNode,id,name);
					},
					createChildNode:function(treeNode,id,name){	//创建一个operate操作-节点
						return that.parent.nodeType.createOperateNode(treeNode,id,name);
					}
				};
		},
		initOperate:function(){//操作节点
			var that=this;
			this["operate"]={
					panelWidget:new OperatePanelWgt(this.$div,this.parent),
					canRename:function(){return true;},
					btnHtml:function(treeId, treeNode){	// 删除节点，删除当前节点
						return "<span class='diy diy_delete node-operate'  treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='删除' "+
						that.parent.nodeType.deleteBtnAppendStyle(treeNode)+"/>";
					},
					disableFieldProperties:function(){
						this.$id.css('display','none');
					}
				};
		},
		initParamDesc:function(){//参数节点
			var that=this;
			this["param-desc"]={
					btnHtml:function(treeId, treeNode){
						// 		增加 参数节点按钮， 导入参数按钮
						var style=(treeNode.nodeType=='out-param-desc'&&treeNode.children&&treeNode.children.length>0)?'style=" display:none" ':'';
						return "<span class='diy diy_add "+treeNode.nodeType+"'  treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='增加参数' "+
						that.parent.nodeType.addBtnAppendStyle(treeNode)+style+"/>";
					},
					canRename:function(){return false;},
					createChildNode:function(treeNode,name,prop){	//创建一个param参数-节点
						var operateIndex=OperateTree.treeNodeCount++;
						return $.extend({
							id : "operateTree" + operateIndex,
							operateId:-operateIndex,
							pId : treeNode.id,
							isParent : false,
							name:name||'',
							inOut:treeNode.nodeType=='in-param-desc'?1:0,
							nodeType:'param'
						},prop||{});
					}
				};	
		},
		initInOutParamDesc:function(){
			this["in-param-desc"]=$.extend({
					panelWidget:new DescPanelWgt(this.$div,this.parent,"点击增加按钮，添加“入参”<br/>点击导入按钮，从协议中导入字段")
				},this["param-desc"]);
			
			this["out-param-desc"]=$.extend({
					panelWidget:new DescPanelWgt(this.$div,this.parent,"点击增加按钮，添加“出参”<br/>点击导入按钮，从协议中导入字段")
				},this["param-desc"]);
		},
		initParam:function(){//参数节点
			var that=this;
			this["param"]={
					panelWidget:new ParamPanelWgt(this.$div,this.parent),
					canRename:function(){return true;},
					btnHtml:function(treeId, treeNode){
						// 删除节点，删除当前节点
						return "<span class='diy diy_delete node-param'  treeId='"+treeId+"' treeTId='"+treeNode.tId+"' title='删除' "+
						that.parent.nodeType.deleteBtnAppendStyle(treeNode)+"/>";
					}
				};
		},
		addBtnAppendStyle:function(treeNode){//增加按钮，在webService类型下不能使用
			var res='';
			//if(this.parent.serviceProp.getServiceType()=='2')
			//	res='style="display:none"';
			return res;
		},
		deleteBtnAppendStyle:function(treeNode){//删除按钮，在webService下只有operate-node可用
			var res='';
			//if(this.parent.serviceProp.getServiceType()=='2'&&treeNode.nodeType!='operate')
			//	res="style='display:none'";
			return res;
		},
		groupBtnAppendStyle:function(treeNode){//组按钮，在http下的group-node,node-root节点可用
			var res='';
			if(!(this.parent.serviceProp.getServiceType()=='3'&&(treeNode.nodeType=='root'||treeNode.nodeType=='group')))
				res='style="display:none"';
			return res;
		},
		nodeBtnShow:function(){
			var operateTree=this.parent.operateTree,
				serviceType=this.parent.serviceProp.getServiceType();
			//webService, 是否   addBtn不显示， 除operate-node的deleteBtn不显示
			if(serviceType=='2')
			{
			//	$('.diy_add',operateTree.$tree).css("display","none");
			//	$('.diy_delete',operateTree.$tree).not('.node-operate').css("display","none");
			}
			else
			{
				$('.diy_add',operateTree.$tree).css("display","inline-block");
				$('.diy_delete',operateTree.$tree).not('.node-operate').css("display","inline-block");
				//限制出参只有一个
				var outParamNodes=$('.out-param-desc',operateTree.$tree);
				$.each(outParamNodes,function(index,node){
					var $node=$(node),treeNode=operateTree.ztreeObj.getNodeByTId($node.attr('treeTId'))
					treeNode.children&&treeNode.children.length==1&&$node.css('display','none')||$node.css('display','inline-block')
				});
			}	
			
			//http,是否显示groupBtn
			if(serviceType=='3')
				$('.diy_add_group',operateTree.$tree).css("display","inline-block");
			else	
				$('.diy_add_group',operateTree.$tree).css("display","none");
		},
		init:function(){
			this.initRoot();
			this.initGroup();
			this.initOperate();
			this.initParamDesc();
			this.initInOutParamDesc();
			this.initParam();
		},
		"root":{},
		"operate":{},
		"param-desc":{},
		"in-param-desc":{},
		"out-param-desc":{},
		"param":{}
	};
	
	// 或者通过 module.exports 提供整个接口
	module.exports=ServiceOperatePlugin;
});